package com.ziji.springsc.formlogin2.component;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("ziji").password("123").roles("admin")
                .and().withUser("zeng").password("123").roles("admin");
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/js/**", "/css/**","/images/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()

                .and()
                // 标记 formLogin 设置开始
                // 这里创建 FormLoginConfigurer 对象，FormLoginConfigurer 是 AbstractAuthenticationFilterConfigurer 的子类
                // 在 AbstractAuthenticationFilterConfigurer 的构造器中 默认设置了 loginPage = "/login"
                .formLogin()
                .loginPage("/login.html")
                // 设置客户端 form 标签的 action 地址值，默认使用 loginPage 的值
                .loginProcessingUrl("/doLogin")
                // 设置请求参数名称（客户端 input[name] 的值）
                .usernameParameter("name")
                .passwordParameter("passwd")
//                // successForwardUrl: 登录成功后，请求将被转发到 /hello， 该方法已经无法使用了!!!
//                .successForwardUrl("/hello")
                // 如果用户进入 loginPage 之前存在前置页面（或者 url），登录成功后则跳转到前置页面
                // 如果用户进入 loginPage 之前不存在前置页面（或者 url），登录成功后则跳转到默认的 /hello 页面（或者 url）
                .defaultSuccessUrl("/hello")
//                // 等效于原来的 successForwardUrl(...) 方法
//                .defaultSuccessUrl("/hello", true)

//                // 设置"登录失败后转发的 url"， 该方法已经无法使用了!!!
//                .failureForwardUrl("/error_page_01")
                // 设置"登录失败后重定向的 url"
                .failureUrl("/error_page_02")
                // 标记 formLogin 设置完成
                .permitAll()

                .and()
                // 开始设置 注销
                .logout()
                // 默认的注销 url 是 /logout
                .logoutUrl("/doLogout")
//                // 设置注销请求的"请求方式"
//                .logoutRequestMatcher(new AntPathRequestMatcher("doLogout_02", "POST"))
                // 注销成功后需要转跳的页面， 这样设置后， /index 成为了一个无需登录即可访问的 url
                .logoutSuccessUrl("/index")
                // 清除 cookie
                .deleteCookies()
                // 清除认证信息和 session（默认 true，所以通常不用设置）
                .clearAuthentication(true)
                .invalidateHttpSession(true)
                // 标记 logout 设置完成
                .permitAll()

                .and()
                .csrf().disable();
    }
}
